﻿using Microsoft.Practices.Prism.Events;
using Neudesic.Pulse.Events;
using Neudesic.Pulse.Infrastructure;
using Neudesic.Pulse.Services;
using System.ComponentModel.Composition;
using System.Diagnostics.Contracts;

namespace Neudesic.Pulse.ViewModels
{

    /// <summary>
    /// View model for submitting status information to the system.
    /// </summary>
    [Export(typeof(StatusViewModel))]
    [PartCreationPolicy(CreationPolicy.Shared)]
    public class StatusViewModel : ViewModel
    {

        private string status;

        /// <summary>
        /// Gets or sets the pulse.
        /// </summary>
        /// <value>The pulse.</value>
        private IPulseGateway Pulse { get; set; }

        /// <summary>
        /// Gets or sets the status.
        /// </summary>
        /// <value>The status.</value>
        public string Status
        {
            get
            { return status; }
            set
            {
                if (!value.Equals(status))
                {
                    status = value;
                    this.RaisePropertyChanged(() => this.Status);
                    Validate();
                }
            }
        }

        private bool canSubmit = false;

        /// <summary>
        /// Gets or sets the can submit.
        /// </summary>
        /// <value>The can submit.</value>
        public bool CanSubmit
        {
            get { return canSubmit; }
            set
            {
                if (!value.Equals(canSubmit))
                {
                    canSubmit = value;
                    this.RaisePropertyChanged(() => this.CanSubmit);
                    this.SubmitStatusCommand.RaiseCanExecuteChanged();
                }
            }
        }

        /// <summary>
        /// Gets or sets the submit status command.
        /// </summary>
        /// <value>The submit status command.</value>
        public AsyncDelegateCommand<bool> SubmitStatusCommand { get; private set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="StatusViewModel" /> class.
        /// </summary>
        /// <param name="pulse">The pulse.</param>
        [ImportingConstructor]
        public StatusViewModel(IEventAggregator eventAggregator, IPulseGateway pulse) : base(eventAggregator)
        {

            this.Pulse = pulse;

            SubmitStatusCommand = new AsyncDelegateCommand<bool>(
                // execute
                () =>
                {
                    Pulse.CreateStatus(Status);
                    return true; // arbitrary
                },
                // can execute
                () => this.CanSubmit,
                // completion
                (b) =>
                {
                    Status = string.Empty; // set back to empty
                    // TODO: Set event for retrieving new entries?  Might not be needed if viewmodel is shared.
                },
                // exception
                (ex) =>
                {
                    if (ex != null)
                    {
                        EventAggregator.GetEvent<ApplicationExceptionEvent>().Publish(ex);
                    }
                }

                );
        }

        private void Validate()
        {
            this.CanSubmit = !string.IsNullOrEmpty(this.Status);
        }

    }
}
